// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"#include "UObject/NoExportTypes.h"#include "MyObject.generated.h"/** * */UCLASS(Blueprintable)class MYPROJECT8_API UMyObject : public UObject{ GENERATED_BODY()};
通过在类声明前添加 UCLASS(Blueprintable) 宏,可以让该类在 UE4 的蓝图编辑器中可见,允许开发者使用蓝图来创建该类的实例、设置属性和调用函数(在蓝图脚本中调用 C++ 的内容)。
可以用 VS 的生成进行编译(有可能 UE4 没反应过来,但可以方便地显示中文的报错信息)。
也可以用 UE4 的 Compile 按钮编译。
此时所创建的类就可以 Create Blueprint class based on MyObject。
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"#include "UObject/NoExportTypes.h"#include "MyObject.generated.h"/** * */UCLASS(Blueprintable)class MYPROJECT8_API UMyObject : public UObject{ GENERATED_BODY()public: UMyObject(); UPROPERTY(BlueprintReadWrite) float MyFloat; UFUNCTION(BlueprintCallable) void MyFunction();};
#include "MyActor.h"// Sets default valuesAMyActor::AMyActor(){ // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true;}// Called when the game starts or when spawnedvoid AMyActor::BeginPlay(){ Super::BeginPlay();}// Called every framevoid AMyActor::Tick(float DeltaTime){ Super::Tick(DeltaTime);}
派生自 Actor 的类带有 A 前缀,如 AController。
派生自 Object 的类带有 U 前缀,如 UComponent。
Enums 的前缀是 E,如 EFortificationType。
Interface 的前缀通常是 I,如 lAbilitySystemInterface。
Template 的前缀是 T,如 TArray。
派生自 SWidget 的类 (Slate Ul) 带有前缀 S,如 SButton。
其他类的前缀为字母 F,如 FVector。
看一看 MyActor.h 里的内容,虽然 UCLASS() 没有 Blueprintable,但是也可以执行 Create Blueprint class based on MyObject,这是因为所继承的类 AActor 自带 Blueprintable:
C++
#pragma once#include "CoreMinimal.h"#include "GameFramework/Actor.h"#include "MyActor.generated.h"UCLASS()class MYPROJECT8_API AMyActor : public AActor{ GENERATED_BODY()public: // Sets default values for this actor's properties AMyActor();protected: // Called when the game starts or when spawned virtual void BeginPlay() override;public: // Called every frame virtual void Tick(float DeltaTime) override;};
#pragma once#include "CoreMinimal.h"#include "GameFramework/Actor.h"#include "MyActor.generated.h"UCLASS()class MYPROJECT8_API AMyActor : public AActor{ GENERATED_BODY()public: // Sets default values for this actor's properties AMyActor(); UPROPERTY(VisibleAnywhere, Category = "My Actor Components") UStaticMeshComponent* MyStaticMesh;protected: // Called when the game starts or when spawned virtual void BeginPlay() override;public: // Called every frame virtual void Tick(float DeltaTime) override;};
编辑 MyActor.cpp 里的内容,在构造函数里设置 MyStaticMesh 里的值:
C++
#include "MyActor.h"// Sets default valuesAMyActor::AMyActor(){ // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; MyStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MyStaticMesh"));}// Called when the game starts or when spawnedvoid AMyActor::BeginPlay(){ Super::BeginPlay();}// Called every framevoid AMyActor::Tick(float DeltaTime){ Super::Tick(DeltaTime);}
修改 MyActor.h 的内容,添加一个 FVector 类型的变量 InitLocation,上面添加修饰宏 UPROPERTY(EditInstanceOnly, Category = "My Actor Properties | Vector"),让这个值可以在实例中编辑:
C++
#pragma once#include "CoreMinimal.h"#include "GameFramework/Actor.h"#include "MyActor.generated.h"UCLASS()class MYPROJECT8_API AMyActor : public AActor{ GENERATED_BODY()public: // Sets default values for this actor's properties AMyActor(); UPROPERTY(VisibleAnywhere, Category = "My Actor Components") UStaticMeshComponent* MyStaticMesh; UPROPERTY(EditInstanceOnly, Category = "My Actor Properties | Vector") FVector InitLocation;protected: // Called when the game starts or when spawned virtual void BeginPlay() override;public: // Called every frame virtual void Tick(float DeltaTime) override;};
修改 MyActor.cpp 里的内容,在 BeginPlay() 中将 Actor 的坐标设为 InitLocation 的值。
C++
#include "MyActor.h"// Sets default valuesAMyActor::AMyActor(){ // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; MyStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MyStaticMesh")); InitLocation = FVector(0.0f);}// Called when the game starts or when spawnedvoid AMyActor::BeginPlay(){ Super::BeginPlay(); SetActorLocation(InitLocation);}// Called every framevoid AMyActor::Tick(float DeltaTime){ Super::Tick(DeltaTime);}
#pragma once#include "CoreMinimal.h"#include "GameFramework/Actor.h"#include "MyActor.generated.h"UCLASS()class MYPROJECT8_API AMyActor : public AActor{ GENERATED_BODY()public: // Sets default values for this actor's properties AMyActor(); UPROPERTY(VisibleAnywhere, Category = "My Actor Components") UStaticMeshComponent* MyStaticMesh; UPROPERTY(EditInstanceOnly, Category = "My Actor Properties | Vector") FVector InitLocation; UPROPERTY(VisibleInstanceOnly, Category = "My Actor Properties | Vector") FVector PlacedLocation; UPROPERTY(EditDefaultsOnly, Category = "My Actor Properties | Vector") bool bGotoInitLocation;protected: // Called when the game starts or when spawned virtual void BeginPlay() override;public: // Called every frame virtual void Tick(float DeltaTime) override;};
修改 MyActor.cpp 里的内容:
C++
#include "MyActor.h"// Sets default valuesAMyActor::AMyActor(){ // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; MyStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MyStaticMesh")); InitLocation = FVector(0.0f); PlacedLocation = FVector(0.0f); bGotoInitLocation = false;}// Called when the game starts or when spawnedvoid AMyActor::BeginPlay(){ Super::BeginPlay(); PlacedLocation = GetActorLocation(); if (bGotoInitLocation) SetActorLocation(InitLocation);}// Called every framevoid AMyActor::Tick(float DeltaTime){ Super::Tick(DeltaTime);}
#pragma once#include "CoreMinimal.h"#include "GameFramework/Actor.h"#include "MyActor.generated.h"UCLASS()class MYPROJECT8_API AMyActor : public AActor{ GENERATED_BODY()public: // Sets default values for this actor's properties AMyActor(); UPROPERTY(VisibleAnywhere, Category = "My Actor Components") UStaticMeshComponent* MyStaticMesh; UPROPERTY(EditInstanceOnly, Category = "My Actor Properties | Vector") FVector InitLocation; UPROPERTY(VisibleInstanceOnly, Category = "My Actor Properties | Vector") FVector PlacedLocation; UPROPERTY(EditDefaultsOnly, Category = "My Actor Properties | Vector") bool bGotoInitLocation; UPROPERTY(VisibleDefaultsOnly, Category = "My Actor Properties | Vector") FVector WorldOrigin; UPROPERTY(EditAnywhere, Category = "My Actor Properties | Vector") FVector TickLoactionOffset; UPROPERTY(EditAnywhere, Category = "My Actor Properties | Vector") bool bShouldMove;protected: // Called when the game starts or when spawned virtual void BeginPlay() override;public: // Called every frame virtual void Tick(float DeltaTime) override;};
修改 MyActor.cpp 里的内容:
C++
#include "MyActor.h"// Sets default valuesAMyActor::AMyActor(){ // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; MyStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MyStaticMesh")); InitLocation = FVector(0.0f); PlacedLocation = FVector(0.0f); bGotoInitLocation = false; WorldOrigin = FVector(0.0f); TickLoactionOffset = FVector(0.0f); bShouldMove = false;}// Called when the game starts or when spawnedvoid AMyActor::BeginPlay(){ Super::BeginPlay(); PlacedLocation = GetActorLocation(); if (bGotoInitLocation) SetActorLocation(InitLocation);}// Called every framevoid AMyActor::Tick(float DeltaTime){ Super::Tick(DeltaTime); if (bShouldMove) { AddActorLocalOffset(TickLoactionOffset); }}
开跑!此时实例会每帧沿方向 (0.1, 0.1, 0.1) 移动。
408-在编辑器中限制输入值的范围与不要将组件指针设为 EditAnywhere
不要将组件指针设为 EditAnywhere
C++
UPROPERTY(EditAnywhere, Category = "My Actor Components")UStaticMeshComponent* MyStaticMesh;
#pragma once#include "CoreMinimal.h"#include "GameFramework/Actor.h"#include "MyActor.generated.h"UCLASS()class MYPROJECT8_API AMyActor : public AActor{ GENERATED_BODY()public: // Sets default values for this actor's properties AMyActor(); UPROPERTY(VisibleAnywhere, Category = "My Actor Components") UStaticMeshComponent* MyStaticMesh; UPROPERTY(EditInstanceOnly, Category = "My Actor Properties | Vector") FVector InitLocation; UPROPERTY(VisibleInstanceOnly, Category = "My Actor Properties | Vector") FVector PlacedLocation; UPROPERTY(EditDefaultsOnly, Category = "My Actor Properties | Vector") bool bGotoInitLocation; UPROPERTY(VisibleDefaultsOnly, Category = "My Actor Properties | Vector") FVector WorldOrigin; UPROPERTY(EditAnywhere, Category = "My Actor Properties | Vector", meta = (ClampMin = -5.0f, ClampMax = 5.0f, UIMin = -5.0f, UIMax = 5.0f)) FVector TickLoactionOffset; UPROPERTY(EditAnywhere, Category = "My Actor Properties | Vector") bool bShouldMove; UPROPERTY(EditInstanceOnly, Category = "My Actor Properties | Physics") FVector InitForce; UPROPERTY(EditInstanceOnly, Category = "My Actor Properties | Physics") FVector InitTorque; UPROPERTY(EditInstanceOnly, Category = "My Actor Properties | Physics") bool bAccelChange;protected: // Called when the game starts or when spawned virtual void BeginPlay() override;public: // Called every frame virtual void Tick(float DeltaTime) override;};
修改 MyActor.cpp 里的内容:
C++
#include "MyActor.h"#include "Components/StaticMeshComponent.h"// Sets default valuesAMyActor::AMyActor(){ // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; MyStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MyStaticMesh")); InitLocation = FVector(0.0f); PlacedLocation = FVector(0.0f); bGotoInitLocation = false; WorldOrigin = FVector(0.0f); TickLoactionOffset = FVector(0.0f); bShouldMove = false; InitForce = FVector(0.0f); InitTorque = FVector(0.0f); bAccelChange = false;}// Called when the game starts or when spawnedvoid AMyActor::BeginPlay(){ Super::BeginPlay(); PlacedLocation = GetActorLocation(); if (bGotoInitLocation) SetActorLocation(InitLocation); MyStaticMesh->AddForce(InitForce, "NAME_None", bAccelChange); MyStaticMesh->AddTorque(InitForce, "NAME_None", bAccelChange);}// Called every framevoid AMyActor::Tick(float DeltaTime){ Super::Tick(DeltaTime); if (bShouldMove) { AddActorLocalOffset(TickLoactionOffset); }}
#include "MyActor.h"#include "Components/StaticMeshComponent.h"// Sets default valuesAMyActor::AMyActor(){ // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; MyStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MyStaticMesh")); InitLocation = FVector(0.0f); PlacedLocation = FVector(0.0f); bGotoInitLocation = false; WorldOrigin = FVector(0.0f); TickLoactionOffset = FVector(0.0f); bShouldMove = false; InitForce = FVector(0.0f); InitTorque = FVector(0.0f); bAccelChange = false;}// Called when the game starts or when spawnedvoid AMyActor::BeginPlay(){ Super::BeginPlay(); PlacedLocation = GetActorLocation(); if (bGotoInitLocation) SetActorLocation(InitLocation); //MyStaticMesh->AddForce(InitForce, "NAME_None", bAccelChange); //MyStaticMesh->AddTorque(InitForce, "NAME_None", bAccelChange);}// Called every framevoid AMyActor::Tick(float DeltaTime){ Super::Tick(DeltaTime); if (bShouldMove) { AddActorLocalOffset(TickLoactionOffset, true); }}
#include "MyActor.h"#include "Components/StaticMeshComponent.h"// Sets default valuesAMyActor::AMyActor(){ // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; MyStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MyStaticMesh")); InitLocation = FVector(0.0f); PlacedLocation = FVector(0.0f); bGotoInitLocation = false; WorldOrigin = FVector(0.0f); TickLoactionOffset = FVector(0.0f); bShouldMove = false; InitForce = FVector(0.0f); InitTorque = FVector(0.0f); bAccelChange = false;}// Called when the game starts or when spawnedvoid AMyActor::BeginPlay(){ Super::BeginPlay(); PlacedLocation = GetActorLocation(); if (bGotoInitLocation) SetActorLocation(InitLocation); //MyStaticMesh->AddForce(InitForce, "NAME_None", bAccelChange); //MyStaticMesh->AddTorque(InitForce, "NAME_None", bAccelChange);}// Called every framevoid AMyActor::Tick(float DeltaTime){ Super::Tick(DeltaTime); if (bShouldMove) { FHitResult HitResult; AddActorLocalOffset(TickLoactionOffset, true, &HitResult); UE_LOG(LogTemp, Warning, TEXT("X: %f, Y: %f, Z: %f"), HitResult.Location.X, HitResult.Location.Y, HitResult.Location.Z); }}
开跑!Output Log 将输出碰撞信息。
414-其他常用函数与可探索部分
略。
501-创建自己的 Pawn 类、自己的根组件并将静态网格组件附加到其上
创建一个 Pawn 类型的 C++ Class,获得 MyPawn.h 和 MyPawn.cpp。
编辑 MyPawn.h,定义变量 class UStaticMeshComponent* MyStaticMesh;,这个 class 可加可不加:
C++
#include "CoreMinimal.h"#include "GameFramework/Pawn.h"#include "MyPawn.generated.h"UCLASS()class MYPROJECT8_API AMyPawn : public APawn{ GENERATED_BODY()public: // Sets default values for this pawn's properties AMyPawn(); UPROPERTY(VisibleAnywhere, Category = "My Pawn Components") class UStaticMeshComponent* MyStaticMesh;protected: // Called when the game starts or when spawned virtual void BeginPlay() override;public: // Called every frame virtual void Tick(float DeltaTime) override; // Called to bind functionality to input virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
#include "MyPawn.h"#include "Components/StaticMeshComponent.h"// Sets default valuesAMyPawn::AMyPawn(){ // Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent")); MyStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MyStaticMesh")); MyStaticMesh->SetupAttachment(GetRootComponent());}// Called when the game starts or when spawnedvoid AMyPawn::BeginPlay(){ Super::BeginPlay();}// Called every framevoid AMyPawn::Tick(float DeltaTime){ Super::Tick(DeltaTime);}// Called to bind functionality to inputvoid AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent){ Super::SetupPlayerInputComponent(PlayerInputComponent);}
编译。Create Blueprint class based on MyPawn。
开跑!
502-为自己的 Pawn 设置相机组件
修改 MyPawn.h,定义一个新的变量 class UCameraComponent* MyCamera;:
C++
#pragma once#include "CoreMinimal.h"#include "GameFramework/Pawn.h"#include "MyPawn.generated.h"UCLASS()class MYPROJECT8_API AMyPawn : public APawn{ GENERATED_BODY()public: // Sets default values for this pawn's properties AMyPawn(); UPROPERTY(VisibleAnywhere, Category = "My Pawn Components") class UStaticMeshComponent* MyStaticMesh; UPROPERTY(VisibleAnywhere, Category = "My Pawn Components") class UCameraComponent* MyCamera;protected: // Called when the game starts or when spawned virtual void BeginPlay() override;public: // Called every frame virtual void Tick(float DeltaTime) override; // Called to bind functionality to input virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;};
修改 MyPawn.cpp,设置好 MyCamera 的属性:
C++
#include "MyPawn.h"#include "Components/StaticMeshComponent.h"#include "Camera/CameraComponent.h"// Sets default valuesAMyPawn::AMyPawn(){ // Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent")); MyStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MyStaticMesh")); MyStaticMesh->SetupAttachment(GetRootComponent()); MyCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("MyCamera")); MyCamera->SetupAttachment(GetRootComponent()); MyCamera->SetRelativeLocation(FVector(-300.0f, 0.0f, 300.0f)); MyCamera->SetRelativeRotation(FRotator(-45.0f, 0.0f, 0.0f));}// Called when the game starts or when spawnedvoid AMyPawn::BeginPlay(){ Super::BeginPlay();}// Called every framevoid AMyPawn::Tick(float DeltaTime){ Super::Tick(DeltaTime);}// Called to bind functionality to inputvoid AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent){ Super::SetupPlayerInputComponent(PlayerInputComponent);}
开跑!
503-设置 GameMode 并自动持有 Pawn
对于 C++ Classes 下的 GameModeBase,创建游戏模式蓝图 Create Blueprint class based on ...。
在创建的蓝图中的 Class Defaults,将 Default Pawn Class 设置为 BP_MyPawn。
关卡中的 World Settings,设置好 GameMode Override。
BP_MyPawn 中设置好 Auto Possess Player 为 Player 0,或者直接修改 MyPawn.cpp,添加语句 AutoPossessPlayer = EAutoReceiveInput::Player0;:
C++
#include "MyPawn.h"#include "Components/StaticMeshComponent.h"#include "Camera/CameraComponent.h"// Sets default valuesAMyPawn::AMyPawn(){ // Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent")); MyStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MyStaticMesh")); MyStaticMesh->SetupAttachment(GetRootComponent()); MyCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("MyCamera")); MyCamera->SetupAttachment(GetRootComponent()); MyCamera->SetRelativeLocation(FVector(-300.0f, 0.0f, 300.0f)); MyCamera->SetRelativeRotation(FRotator(-45.0f, 0.0f, 0.0f)); AutoPossessPlayer = EAutoReceiveInput::Player0;}// Called when the game starts or when spawnedvoid AMyPawn::BeginPlay(){ Super::BeginPlay();}// Called every framevoid AMyPawn::Tick(float DeltaTime){ Super::Tick(DeltaTime);}// Called to bind functionality to inputvoid AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent){ Super::SetupPlayerInputComponent(PlayerInputComponent);}
504-按键映射与轴事件绑定
在 Project Settings 力设置按键映射。
在 MyPawn.h 里定义私有的移动函数:
C++
#pragma once#include "CoreMinimal.h"#include "GameFramework/Pawn.h"#include "MyPawn.generated.h"UCLASS()class MYPROJECT8_API AMyPawn : public APawn{ GENERATED_BODY()public: // Sets default values for this pawn's properties AMyPawn(); UPROPERTY(VisibleAnywhere, Category = "My Pawn Components") class UStaticMeshComponent* MyStaticMesh; UPROPERTY(VisibleAnywhere, Category = "My Pawn Components") class UCameraComponent* MyCamera;protected: // Called when the game starts or when spawned virtual void BeginPlay() override;public: // Called every frame virtual void Tick(float DeltaTime) override; // Called to bind functionality to input virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;private: void MoveForward(float Value); void MoveRight(float Value);};
MyPawn.cpp 里将按键映射与轴事件绑定:
C++
#include "MyPawn.h"#include "Components/StaticMeshComponent.h"#include "Camera/CameraComponent.h"#include "Components/InputComponent.h"// Sets default valuesAMyPawn::AMyPawn(){ // Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent")); MyStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MyStaticMesh")); MyStaticMesh->SetupAttachment(GetRootComponent()); MyCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("MyCamera")); MyCamera->SetupAttachment(GetRootComponent()); MyCamera->SetRelativeLocation(FVector(-300.0f, 0.0f, 300.0f)); MyCamera->SetRelativeRotation(FRotator(-45.0f, 0.0f, 0.0f)); AutoPossessPlayer = EAutoReceiveInput::Player0;}// Called when the game starts or when spawnedvoid AMyPawn::BeginPlay(){ Super::BeginPlay();}// Called every framevoid AMyPawn::Tick(float DeltaTime){ Super::Tick(DeltaTime);}// Called to bind functionality to inputvoid AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent){ Super::SetupPlayerInputComponent(PlayerInputComponent); PlayerInputComponent->BindAxis(TEXT("MoveForward"), this, &AMyPawn::MoveForward); PlayerInputComponent->BindAxis(TEXT("MoveRight"), this, &AMyPawn::MoveRight);}void AMyPawn::MoveForward(float Value){}void AMyPawn::MoveRight(float Value){}
505-使用 Tick 的移动
修改 MyActor.h 里的内容,定义变量 MaxSpeed 和 Velocity:
C++
#pragma once#include "CoreMinimal.h"#include "GameFramework/Pawn.h"#include "MyPawn.generated.h"UCLASS()class MYPROJECT8_API AMyPawn : public APawn{ GENERATED_BODY()public: // Sets default values for this pawn's properties AMyPawn(); UPROPERTY(VisibleAnywhere, Category = "My Pawn Components") class UStaticMeshComponent* MyStaticMesh; UPROPERTY(VisibleAnywhere, Category = "My Pawn Components") class UCameraComponent* MyCamera; UPROPERTY(EditAnywhere, Category = "My Pawn Movement") float MaxSpeed;protected: // Called when the game starts or when spawned virtual void BeginPlay() override;public: // Called every frame virtual void Tick(float DeltaTime) override; // Called to bind functionality to input virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;private: void MoveForward(float Value); void MoveRight(float Value); FVector Velocity;};
#include "MyPawn.h"#include "Components/StaticMeshComponent.h"#include "Camera/CameraComponent.h"#include "Components/InputComponent.h"// Sets default valuesAMyPawn::AMyPawn(){ // Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent")); MyStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MyStaticMesh")); MyStaticMesh->SetupAttachment(GetRootComponent()); MyCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("MyCamera")); MyCamera->SetupAttachment(GetRootComponent()); MyCamera->SetRelativeLocation(FVector(-300.0f, 0.0f, 300.0f)); MyCamera->SetRelativeRotation(FRotator(-45.0f, 0.0f, 0.0f)); AutoPossessPlayer = EAutoReceiveInput::Player0; MaxSpeed = 300.0f; Velocity = FVector::ZeroVector;}// Called when the game starts or when spawnedvoid AMyPawn::BeginPlay(){ Super::BeginPlay();}// Called every framevoid AMyPawn::Tick(float DeltaTime){ Super::Tick(DeltaTime); AddActorLocalOffset(Velocity * DeltaTime, true);}// Called to bind functionality to inputvoid AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent){ Super::SetupPlayerInputComponent(PlayerInputComponent); PlayerInputComponent->BindAxis(TEXT("MoveForward"), this, &AMyPawn::MoveForward); PlayerInputComponent->BindAxis(TEXT("MoveRight"), this, &AMyPawn::MoveRight);}void AMyPawn::MoveForward(float Value){ Velocity.X = FMath::Clamp(Value, -1.0f, 1.0f) * MaxSpeed;}void AMyPawn::MoveRight(float Value){ Velocity.Y = FMath::Clamp(Value, -1.0f, 1.0f) * MaxSpeed;}
修改 MyPawn.h 里的内容,定义变量 class USpringArmComponent* MySpringArm;:
C++
#pragma once#include "CoreMinimal.h"#include "GameFramework/Pawn.h"#include "MyPawn.generated.h"UCLASS()class MYPROJECT8_API AMyPawn : public APawn{ GENERATED_BODY()public: // Sets default values for this pawn's properties AMyPawn(); UPROPERTY(VisibleAnywhere, Category = "My Pawn Components") class UStaticMeshComponent* MyStaticMesh; UPROPERTY(VisibleAnywhere, Category = "My Pawn Components") class UCameraComponent* MyCamera; UPROPERTY(VisibleAnywhere, Category = "My Pawn Components") class USpringArmComponent* MySpringArm; UPROPERTY(EditAnywhere, Category = "My Pawn Movement") float MaxSpeed;protected: // Called when the game starts or when spawned virtual void BeginPlay() override;public: // Called every frame virtual void Tick(float DeltaTime) override; // Called to bind functionality to input virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;private: void MoveForward(float Value); void MoveRight(float Value); FVector Velocity;};